---
title: Checkbox
description: Using the checkbox machine in your project.
package: "@zag-js/checkbox"
---

A checkbox allows users to make a binary choice, i.e. a choice between one of
two possible mutually exclusive options.

<Resources pkg="@zag-js/checkbox" />

<Showcase id="Checkbox" />

**Features**

- Tri-state checkbox. i.e. `indeterminate` state
- Syncs with `disabled` state of fieldset
- Syncs with form `reset` events
- Can be toggled programmatically

## Installation

To use the checkbox machine in your project, run the following command in your
command line:

<CodeSnippet id="checkbox/installation.mdx" />

## Anatomy

To set up the checkbox correctly, you'll need to understand its anatomy and how
we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="checkbox" />

## Usage

First, import the checkbox package into your project

```jsx
import * as checkbox from "@zag-js/checkbox"
```

The checkbox package exports two key functions:

- `machine` — The state machine logic for the checkbox widget.
- `connect` — The function that translates the machine's state to JSX attributes
  and event handlers.

Next, import the required hooks and functions for your framework and use the
checkbox machine in your project 🔥

<CodeSnippet id="checkbox/usage.mdx" />

### Setting the initial checked state

To make a checkbox checked by default, set the context's `defaultChecked`
property to `true`

```jsx {2}
const service = useMachine(checkbox.machine, {
  defaultChecked: true,
})
```

### Indeterminate checkboxes

To make a checkbox indeterminate, set the `defaultChecked` or `checked` property
to `"indeterminate"`

```jsx {2}
const service = useMachine(checkbox.machine, {
  defaultChecked: "indeterminate",
})
```

### Controlled checkbox

To control the checked state programmatically, pass the `checked` and
`onCheckedChange` properties to the machine function.

<CodeSnippet id="checkbox/controlled.mdx" />

### Disabling the checkbox

To make a checkbox disabled, set the context's `disabled` property to true

```jsx {2}
const service = useMachine(checkbox.machine, {
  disabled: true,
})
```

### Listening for changes

When the checkbox value changes, the `onCheckChange` callback is invoked.

```jsx {2-5}
const service = useMachine(checkbox.machine, {
  onCheckChange(details) {
    // details => { checked: boolean }
    console.log("checkbox is:", details.checked)
  },
})
```

### Usage within forms

To use checkbox within forms, use the exposed `api.getHiddenInputProps()` from
the `connect` function and ensure you pass `name` value to the machine's
context.

```jsx {2}
const service = useMachine(checkbox.machine, {
  name: "fruits",
})
```

Next, render the hidden input and ensure the value changes get propagated to the
form correctly.

```jsx
<input {...api.getHiddenInputProps()} />
```

## Styling guide

Earlier, we mentioned that each checkbox part has a `data-part` attribute added
to them to select and style them in the DOM.

### Checked state

When the checkbox input is checked, the `data-state` attribute is added to the
root, control and label parts.

```css
[data-part="root"][data-state="checked|unchecked|indeterminate"] {
  /* styles for when checkbox is checked */
}

[data-part="control"][data-state="checked|unchecked|indeterminate"] {
  /* styles for when checkbox is checked */
}

[data-part="label"][data-state="checked|unchecked|indeterminate"] {
  /* styles for when checkbox is checked */
}
```

### Focused State

When the checkbox input is focused, the `data-focus` attribute is added to the
root, control and label parts.

```css
[data-part="root"][data-focus] {
  /* styles for root focus state */
}

[data-part="control"][data-focus] {
  /* styles for control focus state */
}

[data-part="label"][data-focus] {
  /* styles for label focus state */
}
```

### Disabled State

When the checkbox is disabled, the `data-disabled` attribute is added to the
root, control and label parts.

```css
[data-part="root"][data-disabled] {
  /* styles for root disabled state */
}

[data-part="control"][data-disabled] {
  /* styles for control disabled state */
}

[data-part="label"][data-disabled] {
  /* styles for label disabled state */
}
```

### Invalid State

When the checkbox is invalid, the `data-invalid` attribute is added to the root,
control and label parts.

```css
[data-part="root"][data-invalid] {
  /* styles for root invalid state */
}

[data-part="control"][data-invalid] {
  /* styles for control invalid state */
}

[data-part="label"][data-invalid] {
  /* styles for label invalid state */
}
```

## Methods and Properties

### Machine Context

The checkbox machine exposes the following context properties:

<ContextTable name="checkbox" />

### Machine API

The checkbox `api` exposes the following methods:

<ApiTable name="checkbox" />

### Data Attributes

<DataAttrTable name="checkbox" />

## Accessibility

### Keyboard Interactions

<KeyboardTable name="checkbox" />
